package com.chookss.tiku

import android.util.Log
import android.widget.AbsListView
import android.widget.Adapter
import android.widget.ListView
import androidx.lifecycle.MutableLiveData
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout

/**
 * Company:
 * Project:
 * Author: liuhaoge
 * Date: 2020/11/23 19:47
 * Note:
 */
class ListViewPageHelper {
    var pageSize = 10
    private var nextPageNo = 0
    private var swipeRefreshLayout: SwipeRefreshLayout? = null
    private var mRefreshableView: ListView? = null
    private var isLoading = false
    private var hasMoreData = true
    var onLoadPageListener: OnLoadPageListener? = null
    val loadState = MutableLiveData<LoadState>()
    private var requestPageNo = 0

    fun init(swipeRefreshLayout: SwipeRefreshLayout, listView: ListView) {
        this.swipeRefreshLayout = swipeRefreshLayout
        mRefreshableView = listView
        loadState.postValue(LoadState.Idle)
        swipeRefreshLayout.setOnRefreshListener {
            if (isLoading) {
                swipeRefreshLayout.isRefreshing = false
            } else {
                postLoadPage(0)
            }
        }
        listView.setOnScrollListener(object : AbsListView.OnScrollListener {
            var mLastItemVisible = true
            override fun onScrollStateChanged(view: AbsListView, state: Int) {
                if (state == AbsListView.OnScrollListener.SCROLL_STATE_IDLE && mLastItemVisible && !isLoading) {
                    if (hasMoreData) {
                        postLoadPage(nextPageNo)
                    }
                }
            }

            override fun onScroll(view: AbsListView, firstVisibleItem: Int, visibleItemCount: Int, totalItemCount: Int) {
                mLastItemVisible = isLastItemVisible()
                val enable = isFirstItemVisible()
                if (swipeRefreshLayout.isEnabled != enable) {
                    swipeRefreshLayout.isEnabled = enable
                }
            }
        })
    }

    fun postLoadPage(pageNo: Int) {
        if (onLoadPageListener != null) {
            requestPageNo = pageNo
            isLoading = true
            loadState.postValue(LoadState.Loading)
            onLoadPageListener!!.onLoadPage(requestPageNo, pageSize)
        }
    }


    private fun isFirstItemVisible(): Boolean {
        val adapter: Adapter? = mRefreshableView!!.adapter
        return if (null != adapter && !adapter.isEmpty) {
            if (mRefreshableView!!.firstVisiblePosition <= 1) {
                val firstVisibleChild = mRefreshableView!!.getChildAt(0)
                if (firstVisibleChild != null) {
                    return firstVisibleChild.top >= 0
                }
            }
            false
        } else {
            Log.d("PullToRefresh", "isFirstItemVisible. Empty View.")
            true
        }
    }

    private fun isLastItemVisible(): Boolean {
        val adapter: Adapter? = mRefreshableView!!.adapter
        return if (null != adapter && !adapter.isEmpty) {
            val lastItemPosition = mRefreshableView!!.count - 1
            val lastVisiblePosition = mRefreshableView!!.lastVisiblePosition
            Log.d("PullToRefresh", "isLastItemVisible. Last Item Position: $lastItemPosition Last Visible Pos: $lastVisiblePosition")
            if (lastVisiblePosition >= lastItemPosition - 1) {
                val childIndex = lastVisiblePosition - mRefreshableView!!.firstVisiblePosition
                val lastVisibleChild = mRefreshableView!!.getChildAt(childIndex)
                if (lastVisibleChild != null) {
                    return lastVisibleChild.bottom <= mRefreshableView!!.height
                }
            }
            false
        } else {
            Log.d("PullToRefresh", "isLastItemVisible. Empty View.")
            true
        }
    }


    fun completeLoading(success: Boolean, loadedSize: Int) {
        swipeRefreshLayout!!.isRefreshing = false
        isLoading = false
        if (success) {
            hasMoreData = loadedSize >= pageSize
            nextPageNo = requestPageNo + 1
            if (hasMoreData) {
                loadState.postValue(LoadState.Idle)
            } else {
                loadState.postValue(LoadState.ToEnd)
            }
        } else { //失败的话 认为有更多
            hasMoreData = true
            loadState.postValue(LoadState.Error)
        }
    }

    fun performLoading() {
        postLoadPage(nextPageNo)
    }


    interface OnLoadPageListener {
        fun onLoadPage(pageNo: Int, pageSize: Int)
    }

    enum class LoadState {
        Error, Loading, ToEnd, Idle
    }

}